package com.leizhi.demo.monitor.achieve.listener;

import com.leizhi.demo.monitor.pojo.FrameData;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.CompositeByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import io.netty.handler.codec.MessageToMessageDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @Description UDP RTP 监听器（解码部分）
 * @Version 1.0.0-SNAPSHOT
 * @Author leizhi
 * @Date 2025/4/27 10:10
 */
public class UdpRtpDecoderListener extends MessageToMessageDecoder<DatagramPacket> {

    private static final Logger logger = LoggerFactory.getLogger(UdpRtpDecoderListener.class);


    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket, List<Object> out) throws Exception {
        ByteBuf byteBuf = datagramPacket.content();
        if (byteBuf == null || byteBuf.readableBytes() < 12) {
            if (byteBuf != null) byteBuf.release();
            return;
        }

        CompositeByteBuf composite = channelHandlerContext.alloc().compositeBuffer();
        int offset = 12;

        while (offset < byteBuf.writerIndex()) {
            // 假设每个 NAL Unit 以固定大小分割（实际应解析 FU-A 分片）
            int nalUnitSize = byteBuf.writerIndex() - offset;
            composite.addComponent(true, byteBuf.retainedSlice(offset, nalUnitSize));
            offset += nalUnitSize;
        }

        FrameData frameData = new FrameData(extractSsrc(byteBuf));
        frameData.setComposite(composite);
        out.add(frameData);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        logger.error("UDP 解码器发生异常：", cause);
    }

    private Long extractSsrc(ByteBuf buf) {
        return ((long) (buf.getByte(8) & 0xFF) << 24)
                | ((buf.getByte(9) & 0xFF) << 16)
                | ((buf.getByte(10) & 0xFF) << 8)
                | (buf.getByte(11) & 0xFF);
    }

}
